package com.imooc.distributedemo.web3.client;

import com.alibaba.fastjson.JSON;
import com.imooc.distributedemo.web3.pojo.MyEthBlock;
import lombok.extern.slf4j.Slf4j;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.DefaultBlockParameterNumber;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.core.methods.response.EthBlock.Block;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthTransaction;
import org.web3j.protocol.core.methods.response.Transaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;

import java.math.BigInteger;
import java.util.concurrent.CompletableFuture;

@Slf4j
public class EthRpcCallClient {

    private static final String MY_ETH_ADDRESS = "0x26e598f4843c106a5bb6da553549dc7e2afee016";
    private static final String ETH_SERVER_URL = "https://sepolia.infura.io/v3/753af77cda5240b9a9ea1b28cf192002";
    private Web3j web3j;

    public EthRpcCallClient(Web3j web3j){
        this.web3j = web3j;//Web3j.build(new HttpService("https://sepolia.infura.io/v3/753af77cda5240b9a9ea1b28cf192002"));
    }
    public static void main(String[] args) throws Exception{
        Web3j web3j = Web3j.build(new HttpService(ETH_SERVER_URL));
        EthGetBalance ethGetBalance = web3j.ethGetBalance(MY_ETH_ADDRESS, DefaultBlockParameterName.LATEST).sendAsync().get();
        BigInteger myBalance = ethGetBalance.getBalance();
        System.out.println("我的eth地址余额是:"+myBalance.intValue());
        String hexNumber = Integer.toHexString(myBalance.intValue());
        System.out.println(hexNumber);

        EthRpcCallClient ethCall = new EthRpcCallClient(web3j);
        // 获取最新区块号
        BigInteger latestBlockNumber = web3j.ethBlockNumber().sendAsync().get().getBlockNumber();
        System.out.println("最新的区块:"+latestBlockNumber.intValue());

        BigInteger targetBlockNumber = new BigInteger("6798057"); // 7489486-6798057=7489486-6798057
        String ethBlockByNumber = ethCall.hanldeEthGetBlockByNumber(targetBlockNumber);
        System.out.println("当前区块详细数据:"+ethBlockByNumber);

        String hashData = "0x2383b7b1e78ddfebd99f4ef65479bf4dc194578942bf96ccf60f526de7d019e2";//"0xe4cc9477a4e2b0996db95c7679efabc082146c6092d8207e85dd37f93cc5fd90";
        String blockByHash = ethCall.handleEthGetBlockByHash(hashData);
        System.out.println("根据TransactionHash查出来的HashBlock:"+blockByHash);

        String transactionHash = "0xe4cc9477a4e2b0996db95c7679efabc082146c6092d8207e85dd37f93cc5fd90";
        String transactionByHash = ethCall.handleEthTransactionByHash(transactionHash);
        System.out.println("通过交易hash获取当前交易对:"+transactionByHash);

        String transactionReceiptByHash = ethCall.handleEthTransactionReceipt(transactionHash);
        System.out.println("通过交易hash获取当前交易收据:"+transactionByHash);
    }

    private String handleEthTransactionReceipt(String transactionHash) throws Exception {
        CompletableFuture<EthGetTransactionReceipt> ethGetTransactionReceiptResp = web3j.ethGetTransactionReceipt(transactionHash).sendAsync();
        EthGetTransactionReceipt ethGetTransactionReceipt = ethGetTransactionReceiptResp.get();
        TransactionReceipt result = ethGetTransactionReceipt.getResult();
        String str = JSON.toJSONString(result);
        return str;
    }

    private String handleEthTransactionByHash(String transactionHash) throws Exception {
        CompletableFuture<EthTransaction> ethTransactionResp = web3j.ethGetTransactionByHash(transactionHash).sendAsync();
        EthTransaction ethTransaction = ethTransactionResp.get();
        Transaction result = ethTransaction.getResult();
        String str = JSON.toJSONString(result);
        return str;
    }

    private String handleEthGetBlockByHash(String hashData) throws Exception{
        EthBlock ethBlock = web3j.ethGetBlockByHash(hashData, true).sendAsync().get();
        Block result = ethBlock.getBlock();
        result.setTotalDifficulty("0x0");
        if (result.getTotalDifficulty() == null) {
            result.setTotalDifficulty("0"); // 设置默认值
        }
        String ethBlockJsonStr = JSON.toJSONString(result,true);
        return ethBlockJsonStr;
    }

    /**
     * 根据Block区块号 获取区块信息
     * @param lastKnownBlockNumber
     * @return
     */
    private String hanldeEthGetBlockByNumber(BigInteger lastKnownBlockNumber) {
        String ethBlockJsonStr="";
        try {
            DefaultBlockParameter parameter = new DefaultBlockParameterNumber(lastKnownBlockNumber);
            EthBlock ethBlock = web3j.ethGetBlockByNumber(parameter, true).sendAsync().get();
            EthBlock.Block result = ethBlock.getResult();
            // 检查 getTotalDifficulty 方法的返回值
            // TODO xxx 这里原先为null   设置一下"TotalDifficulty"  不然报错了：
            result.setTotalDifficulty("0x0");
            if (result.getTotalDifficulty() == null) {
                result.setTotalDifficulty("0"); // 设置默认值
            }
            ethBlockJsonStr = JSON.toJSONString(result,true);
            log.info("解析的ethBlock数据是:{}",ethBlockJsonStr);
        }catch (Exception e){
            log.error("通过区块num解析区块数据异常,lastKnownBlockNumber:{}",lastKnownBlockNumber,e);
        }
        return ethBlockJsonStr;
    }
}
